package com.cxb.view;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.hardware.input.InputManager;
import android.os.SystemClock;
import android.util.Log;
import android.view.Gravity;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.ImageView.ScaleType;

import com.cxb.R;
import com.cxb.utils.CommonUtils;
import com.cxb.utils.Constants;
import com.cxb.utils.SharedPreferencesUtils;

public class FloatingView extends View {

	private Context mContext;
	private WindowManager mWindowManager; // WindowManager
	private ActivityManager mActivityManager; // ���ݵ�ǰActivity��������ƽ��������
	private OnFloatViewTouchListener mFloatViewTouchListener;
	private ImageButton mFloatView;
	private long operDur; // ���ڼ�¼�û�����ؼ���ʱ�䣬���Touch�ؼ���ʱ��϶̣�����Ϊ��Touch��һ�ε��
	private SharedPreferencesUtils spUtils;

	public FloatingView(Context context) {
		super(context);
		mContext = context;
		mWindowManager = (WindowManager) mContext
				.getSystemService(Context.WINDOW_SERVICE);
		mActivityManager = (ActivityManager) mContext
				.getSystemService(Context.ACTIVITY_SERVICE);
		spUtils = new SharedPreferencesUtils(context);
	}

	public void showFloatingBtn() {
		mFloatViewTouchListener = new OnFloatViewTouchListener(mWindowManager,
				getFloatViewLayoutParam(mWindowManager));
		mFloatView.setOnTouchListener(mFloatViewTouchListener);

	}

	public void removeView() {
		if (mFloatView != null)
			mFloatView.setVisibility(View.GONE);
	}

	public void ShowView() {
		if (mFloatView != null)
			mFloatView.setVisibility(View.VISIBLE);
	}

	private class OnFloatViewTouchListener implements OnTouchListener {
		private static final long MAX_MILLI_TREAT_AS_CLICK = 100; // ���û����ؿ��ư�ť��ʱ��С�ڸó�������ʱ��������ư�ť��λ�÷����˱仯��Ҳ��Ϊ����һ�ε���¼�

		private WindowManager mWindowManager;
		private WindowManager.LayoutParams mLayoutParams;
		// ��������
		float mLastX, mLastY;

		int mOldOffsetX, mOldOffsetY;
		int mRecordFlag = 0; // �������¼�¼FloatViewλ�õı�־
		long mTouchDur; // ��¼�û����ؿ��ư�ť��ʱ��

		public OnFloatViewTouchListener(WindowManager windowManager,
				WindowManager.LayoutParams layoutParams) {
			mWindowManager = windowManager;
			mLayoutParams = layoutParams;
		}

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			final int action = event.getAction();

			float x = event.getRawX();
			float y = event.getRawY();

			if (mRecordFlag == 0) {
				mOldOffsetX = mLayoutParams.x; // ƫ����
				mOldOffsetY = mLayoutParams.y; // ƫ����
			}

			if (action == MotionEvent.ACTION_DOWN) {
				mFloatView.setImageResource(R.drawable.float_icon_touched);
				mLastX = x;
				mLastY = y;
				mTouchDur = System.currentTimeMillis();

			} else if (action == MotionEvent.ACTION_MOVE) {
				if (Math.abs(x - mLastX) < 0.5 && Math.abs(y - mLastY) < 0.5)
					return true;
				mLayoutParams.x = (int) (x - mLayoutParams.width / 2); // ƫ����
				mLayoutParams.y = (int) (y - mLayoutParams.height / 2); // ƫ����
				mRecordFlag = 1;
				mWindowManager.updateViewLayout(mFloatView, mLayoutParams);

			}

			else if (action == MotionEvent.ACTION_UP) {
				mTouchDur = System.currentTimeMillis() - mTouchDur;
				int newOffsetX = mLayoutParams.x;
				int newOffsetY = mLayoutParams.y;
				spUtils.setVirtualBtnPostion(new Point(newOffsetX, newOffsetY));
				if (mTouchDur < MAX_MILLI_TREAT_AS_CLICK
						|| (mOldOffsetX == newOffsetX && mOldOffsetY == newOffsetY)) {
					// 2
					// if (keyControlDialog.isShowing()) {
					// keyControlDialog.dismiss();
					// } else {
					// keyControlDialog.show();
					// }
					Intent intent = new Intent(
							Constants.IntentData.ACTION_RECEIVE_KEYDOWN_INTENT);
					intent.putExtra(Constants.IntentData.EXTRA_KEY_CODE, 3);
					mContext.sendBroadcast(intent);

					int keycode = KeyEvent.KEYCODE_HOME;
					if ("35S".equals(CommonUtils.getInnerVersionName()))
						keycode = KeyEvent.KEYCODE_F1;
					Log.i("pumkid",
							"code " + keycode + " "
									+ CommonUtils.getInnerVersionName());
					sendEvent(KeyEvent.ACTION_DOWN, 0, keycode);
					sendEvent(KeyEvent.ACTION_UP, 0, keycode);
					// TODO ��ʾ�����ذ�������
				} else {
					mRecordFlag = 0;
				}
				mFloatView.setImageResource(R.drawable.float_icon);
			}
			return true;
		}
	}

	@SuppressLint({ "InlinedApi", "NewApi" })
	private WindowManager.LayoutParams getFloatViewLayoutParam(
			WindowManager windowManager) {
		mFloatView = new ImageButton(getContext());
		mFloatView.setScaleType(ScaleType.CENTER_INSIDE);
		mFloatView.setImageResource(R.drawable.float_icon);
		mFloatView.setBackgroundColor(Color.TRANSPARENT);
		mFloatView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
		// mFloatView.setScaleType(ScaleType.CENTER_INSIDE);
		WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
		layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; // type�ǹؼ��������2002��ʾϵͳ�����ڣ���Ҳ��������2003��
		layoutParams.flags = 40;// �����������ɿ�
		layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
		Point point = spUtils.getVirtualBtnPostion();
		layoutParams.x = point.x;
		layoutParams.y = point.y;
		layoutParams.width = (int) mContext.getResources().getDimension(
				R.dimen.homekey_height);
		layoutParams.height = (int) mContext.getResources().getDimension(
				R.dimen.homekey_height);
		layoutParams.format = -3; // ͸��

		windowManager.addView(mFloatView, layoutParams);
		return layoutParams;
	}

	// private void sendKeyEvent(int keyCode) {
	// int eventCode = keyCode;
	// long now = SystemClock.uptimeMillis();
	// try {
	// KeyEvent down = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, eventCode,
	// 0);
	// KeyEvent up = new KeyEvent(now, now, KeyEvent.ACTION_UP, eventCode, 0);
	// (IWindowManager.Stub
	// .asInterface(ServiceManager.getService("window")))
	// .injectInputEventNoWait(down);
	// (IWindowManager.Stub
	// .asInterface(ServiceManager.getService("window")))
	// .injectInputEventNoWait(up);
	// } catch (RemoteException e) {
	// }
	// }

	void sendEvent(int action, int flags, final int KEYCODE) {
		sendEvent(action, flags, SystemClock.uptimeMillis(), KEYCODE);
	}

	@SuppressLint("NewApi")
	void sendEvent(int action, int flags, long when, final int KEYCODE) {
		long mDownTime = SystemClock.uptimeMillis();

		final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
		final KeyEvent ev = new KeyEvent(mDownTime, when, action, KEYCODE,
				repeatCount, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags
						| KeyEvent.FLAG_FROM_SYSTEM
						| KeyEvent.FLAG_VIRTUAL_HARD_KEY,
				InputDevice.SOURCE_KEYBOARD);
		// InputManager im = (InputManager)
		// mContext.getSystemService(mContext.INPUT_SERVICE);
		Class inc;
		try {
			inc = Class.forName("android.hardware.input.InputManager");
			Method getInstance = inc.getMethod("getInstance");
			InputManager inputManager = (InputManager) getInstance.invoke(inc);
			Method inject = inc.getMethod("injectInputEvent", InputEvent.class,
					int.class);
			inject.invoke(inputManager, ev, 0);

		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
